<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // ES5 的对象属性名都是字符串，这容易造成属性名的冲突。
    // ES5 的对象属性名都是字符串，这容易造成属性名的冲突。比如，你使用了一个他人提供的对象，但又想为这个对象添加新的方法（mixin 模式），新方法的名字就有可能与现有方法产生冲突。如果有一种机制，保证每个属性的名字都是独一无二的就好了，这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。
    

    // var zhang = {
    //     name:"张三",
    //     age:18,
    //     height:"177cm",
    //     weight:"60cm"
    // }

    // zhang.sex = "男"; // 新增属性(没有就新增)
    // zhang.age = 22; // 修改属性(有就修改)

    // console.log(Math);

    // 随机整数  (如果已知重名 => 换一个名字)
    // Math.randInt = function (min, max) {
    //     return min + Math.round(Math.random() * (max - min));
    // }
    
    // ES5 在新增属性名前加前缀"_" ,以方式和Math对象中现有的属性名冲突 
    // Math._random = function (min, max) {
    //     return min + Math.round(Math.random() * (max - min));
    // }
    // console.log(Math);
    
    // var result = Math._random(0,100);
    // console.log(result);
</script>
<script>
    // ES5 的对象属性名都是字符串，这容易造成属性名的冲突。
    // ES5 的对象属性名都是字符串，这容易造成属性名的冲突。比如，你使用了一个他人提供的对象，但又想为这个对象添加新的方法（mixin 模式），新方法的名字就有可能与现有方法产生冲突。如果有一种机制，保证每个属性的名字都是独一无二的就好了，这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。

    // ES6 引入了一种新的原始数据类型Symbol，表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一，其他数据类型是：undefined、null、布尔值（Boolean）、字符串（String）、数值（Number）、大整数（BigInt）、对象（Object）。

    // ES6新增数据类型 Symbol BigInt
    // ES6新增数据结构 Map Set 

    // 如何创建Symbol数据  =>  Symbol 值通过Symbol()函数生成,表示独一无二的值
    var s = Symbol();
    console.log(s,typeof s);   // 'symbol'

    var s1 = Symbol();
    console.log(s1);

    console.log(s === s1);
    console.log(s === s);

    // Symbol()函数可以接受一个字符串作为参数，表示对 Symbol 实例的描述。

    var s = Symbol("a");
    console.log(s);  

    var s1 = Symbol("b");
    console.log(s1);

    console.log(s === s1);

    // 如何获取Symbol数据的描述
    console.log(s.description); // "a"
    console.log(s1.description); // "b"


    // Symbol隐式转字符串
    // var s = Symbol("a");
    // console.log(s,s.toString());  

    // var s1 = Symbol("a");
    // console.log(s1,s1.toString());

    // 间接比较
    // console.log(s.description === s1.description);
    // console.log(s.toString(),s1.toString(),s.toString() == s1.toString()); // "s.toString()"


    // 应用
    // Symbol 表示独一无二的值
    // (1) 作为对象的的属性(字符串/symbol数据) 凡是属性名属于 Symbol 类型，就都是独一无二的，可以保证不会与其他属性名产生冲突。
    // (2) 消除魔术字符串

    var s = Symbol("random");
    console.log(s);

    Math[s] = function (min, max) {
        return min + Math.round(Math.random() * (max - min));
    }
    console.log(Math);

    var result = Math[s](0,100);
    console.log(result);





    



</script>
</html>